package com.cinorecycle.printqrcode.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.cinorecycle.printqrcode.common.PrintParam;
import com.cinorecycle.printqrcode.entity.TestDevicePhone;
import com.cinorecycle.printqrcode.entity.cino.Model;
import com.cinorecycle.printqrcode.entity.result.ResultVo;
import com.cinorecycle.printqrcode.entity.vo.*;
import com.cinorecycle.printqrcode.entity.vo.print.PrintVo;
import com.cinorecycle.printqrcode.entity.vo.test_device_phone_controller.SelectTestDevicePhoneByIdVo;
import com.cinorecycle.printqrcode.util.MatrixToImageWriter;
import com.cinorecycle.printqrcode.util.PdfPrint;
import com.cinorecycle.printqrcode.util.PrintUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.StringUtils;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

import static com.cinorecycle.printqrcode.util.TextQrCode.pressText;

/**
 * TODO
 *
 * @author ER GOU
 * @version 1.0
 * @date 2021/4/1 9:48
 */
@Slf4j
@RestController
public class PrintQrCodeController {

    private static String path = "./imgs";
    private static String url;

    static {
        String property = System.getProperty("user.dir");
        String p = property + "\\config.properties";

        Properties properties = new Properties();

        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(p));
            properties.load(bufferedReader);
        } catch (IOException e) {
            log.info(e.getMessage());
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                log.info(e.getMessage());
            }
        }

        url = properties.getProperty("host");
    }

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private PrintUtils printUtils;

    //打印pc二维码
    @CrossOrigin
    @GetMapping("print-qr-code/{deviceId}/{printName}")
    public ResultVo printQr(@PathVariable String deviceId,@PathVariable String printName) {
        if (StrUtil.isBlank(deviceId)) {
            return ResultVo.fail();
        }
        File f = new File(path);
        if (!f.exists()) {
            f.mkdir();
        }

        try {
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            Map hints = new HashMap();
            //设置UTF-8， 防止中文乱码
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            //设置二维码四周白色区域的大小
            hints.put(EncodeHintType.MARGIN, 1);
            //设置二维码的容错性
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

            //width:图片完整的宽;height:图片完整的高
            //因为要在二维码下方附上文字，所以把图片设置为长方形（高大于宽）
            //int width = 500;//352
            //int height = 300;//612
            int width = PrintParam.areaWith;//352
            int height = PrintParam.areaHeight;//612
            //画二维码，记得调用multiFormatWriter.encode()时最后要带上hints参数，不然上面设置无效
            BitMatrix bitMatrix = multiFormatWriter.encode(deviceId + "", BarcodeFormat.QR_CODE, width, height, hints);

            //qrcFile用来存放生成的二维码图片（无logo，无文字）
            //File logoFile = new File(path, "logo.jpg");

            //开始画二维码
            BufferedImage barCodeImage = MatrixToImageWriter.writeToFile(bitMatrix, "jpg");

            //在二维码中加入图片
            //LogoConfig logoConfig = new LogoConfig(); //LogoConfig中设置Logo的属性
            //BufferedImage image = addLogo_QRCode(barCodeImage, logoFile, logoConfig);

            int font = 15; //字体大小
            int fontStyle = 1; //字体风格

            //用来存放带有logo+文字的二维码图片
            long t = System.currentTimeMillis();
            String newImageWithText = path + "/" + t + ".jpg";
            //附加在图片上的文字信息
            String getComputerVoInfoUrl = url + "/cinorecycle/all-in-one/id/" + deviceId;
            ResultVo resultVo = restTemplate.getForObject(getComputerVoInfoUrl, ResultVo.class);
            String s = JSON.toJSONString(resultVo.getData());
            AllSelectById2 allSelectById2 = JSON.parseObject(s, AllSelectById2.class);
            PcVo pcVo = allSelectById2.getPcVo();
            List<MemoryVo2> memoryVo2s = allSelectById2.getMemoryVo2s();
            List<GpuVo2> gpuVo2s = allSelectById2.getGpuVo2s();
            List<DiskVo2> diskVo2s = allSelectById2.getDiskVo2s();

            //内存
            String memoryStr = "";
            if (!CollectionUtils.isEmpty(memoryVo2s) && memoryVo2s.get(0) != null) {
                for (int i = 0; i < memoryVo2s.size(); i++) {
                    MemoryVo2 memoryVo2 = memoryVo2s.get(i);
                    if (i != 0) {
                        memoryStr += "+";
                    }
                    memoryStr += memoryVo2.getMemorySize();
                }
            }

            //硬盘
            String diskStr = "";
            if (!CollectionUtils.isEmpty(diskVo2s) && diskVo2s.get(0) != null) {
                for (int i = 0; i < diskVo2s.size(); i++) {
                    DiskVo2 diskVo2 = diskVo2s.get(i);
                    diskStr += (diskVo2.getDiskType() + " " + diskVo2.getDiskCapacity() + " ");
                }
                diskStr += "\n";
            }

            //GPU
            String gpuStr = "";
            if (!CollectionUtils.isEmpty(gpuVo2s) && gpuVo2s.get(0) != null) {
                for (int i = 0; i < gpuVo2s.size(); i++) {
                    GpuVo2 gpuVo2 = gpuVo2s.get(i);
                    gpuStr += (gpuVo2.getGpuModel() + "\n");
                }
            }
            String text =
                    pcVo.getPoId() +
                            "\n"
                            + pcVo.getPcId()
                            + "\n"
                            + pcVo.getPcSn()
                            + "\n"
                            + pcVo.getPcModel()
                            + "\n";

            String cpuStr = "";
            if (pcVo.getCpuCount() != 0) {
                String cpuModel = pcVo.getModelCpuName();
                String[] cms = cpuModel.split("\\s+");
                cpuStr = Arrays.stream(cms).filter(c -> !(c.contains("Intel") ||
                        c.contains("Core") ||
                        c.contains("Xeon") ||
                        c.contains("Celeron") ||
                        c.contains("Pentium") ||
                        c.contains("@") ||
                        c.contains("GHz") ||
                        c.contains("CPU") ||
                        c.contains("AMD")))
                        .collect(Collectors.joining(" "));
                cpuStr = (pcVo.getCpuCount() == 1 ? "" : (pcVo.getCpuCount() + "*")) + cpuStr;
            }


            if (StrUtil.isNotBlank(cpuStr)) {
                text += (cpuStr + "\n");
            }
            if (!memoryStr.equalsIgnoreCase("")) {
                text += (memoryStr + "\n");
            }
            if (!gpuStr.equalsIgnoreCase("")) {
                text += gpuStr;
            }
            if (!diskStr.equalsIgnoreCase("")) {
                text += diskStr;
            }
            String s1 = (pcVo.getPassed() ? "PASS" : "FAIL") + " " + pcVo.getQuality() + "\n";
            text += s1;
            if (!StrUtil.isBlank(pcVo.getMark())) {
                text += ("备注: " + pcVo.getMark());
            }
            //text += ("GTX960M\n8G+8G\nSSD 500GB SSD 1TB\n备注: 测试测试");

            //在二维码下方添加文字（文字居中）
            pressText(text, newImageWithText, barCodeImage, fontStyle, Color.black, font, width, height);

            String pdfPath = path + "/" + t + ".pdf";

            PdfPrint.toPdf(newImageWithText, pdfPath);

            File file = new File(pdfPath);
            //等待图片生成
            while (!file.exists()) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("生成");

            PdfPrint.PDFprint(file, printName);

        } catch (Exception e) {
            return ResultVo.fail();

        }
        return ResultVo.ok();

    }

    //打印其他设备二维码
    @CrossOrigin
    @GetMapping("print-qr-code/others/{deviceId}/{printName}")
    public ResultVo printOtherQr(@PathVariable String deviceId,@PathVariable String printName) {
        if (StrUtil.isBlank(deviceId)) {
            return ResultVo.fail();
        }
        try {
            PrintVo printVo = printUtils.commonPrint(deviceId);
            DeviceOthersVo deviceOthersVo = JSON.parseObject(printVo.getString(), DeviceOthersVo.class);

            String deviceBrand = deviceOthersVo.getDeviceBrand();
            String deviceModel = deviceOthersVo.getDeviceModel();
            String sn = deviceOthersVo.getSn();
            String id = deviceOthersVo.getId();
            String quality = deviceOthersVo.getQuality();
            Boolean passed = deviceOthersVo.getPassed();
            String mark = deviceOthersVo.getMark();
            String property = deviceOthersVo.getProperty();
            String text = (deviceOthersVo.getPoId() + "\n" + id + "\n" + sn + "\n");
            if (StrUtil.isNotBlank(deviceBrand)) {
                text += (deviceBrand + "\n");
            }
            if (StrUtil.isNotBlank(deviceModel)) {
                text += (deviceModel + "\n");
            }
            if (StrUtil.isNotBlank(property)) {
                text += (property + "\n");
            }
            text = text + ((passed ? "PASS" : "FAIL") + " " + quality + "\n" + (StrUtil.isBlank(mark) ? "" : mark));

            //在二维码下方添加文字（文字居中）
            pressText(text, printVo.getNewImageWithText(), printVo.getBufferedImage(), printVo.getFontStyle(), Color.black, printVo.getFont(), printVo.getWidth(), printVo.getHeight());

            String pdfPath = path + "/" + printVo.getTime() + ".pdf";

            PdfPrint.toPdf(printVo.getNewImageWithText(), pdfPath);

            File file = new File(pdfPath);
            //等待图片生成
            while (!file.exists()) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("生成");

            PdfPrint.PDFprint(file, printName);

        } catch (Exception e) {
            return ResultVo.fail();

        }
        return ResultVo.ok();

    }

    //打印手机二维码
    @CrossOrigin
    @GetMapping("print-qr-code/mobile/{deviceId}/{printName}")
    public ResultVo printMobileQr(@PathVariable String deviceId,@PathVariable String printName) {
        if (StrUtil.isBlank(deviceId)) {
            return ResultVo.fail();
        }
        try {
            PrintVo printVo = printUtils.commonPrint(deviceId);
            SelectTestDevicePhoneByIdVo selectTestDevicePhoneByIdVo = JSON.parseObject(printVo.getString(), SelectTestDevicePhoneByIdVo.class);

            TestDevicePhone testDevicePhone = selectTestDevicePhoneByIdVo.getTestDevicePhone();
            Model model = selectTestDevicePhoneByIdVo.getModel();
            String model1 = model.getModel();
            String sn = testDevicePhone.getSn();
            String id = testDevicePhone.getId();
            String diskCapacity = testDevicePhone.getDiskCapacity();
            String saleModel = testDevicePhone.getSaleModel();
            String quality = testDevicePhone.getQuality();
            Boolean passed = testDevicePhone.getPassed();
            String mark = testDevicePhone.getMark();
            Boolean isAssociated = testDevicePhone.getIsAssociated();
            String associated;
            if (isAssociated == null) {
                associated = "";
            } else if (isAssociated) {
                associated = "有锁";
            } else {
                associated = "无锁";
            }
            String text = (testDevicePhone.getPoId() + "\n" + id + "\n" + sn + "\n" + model1 + "\n" + diskCapacity + "\n" + (StrUtil.isNotBlank(saleModel) ? saleModel + "\n" : "") + (passed ? "PASS" : "FAIL") + " " + quality + "\n" + associated + "\n" + (StrUtil.isBlank(mark) ? "" : mark));

            //在二维码下方添加文字（文字居中）
            pressText(text, printVo.getNewImageWithText(), printVo.getBufferedImage(), printVo.getFontStyle(), Color.black, printVo.getFont(), printVo.getWidth(), printVo.getHeight());

            String pdfPath = path + "/" + printVo.getTime() + ".pdf";

            PdfPrint.toPdf(printVo.getNewImageWithText(), pdfPath);

            File file = new File(pdfPath);
            //等待图片生成
            while (!file.exists()) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("生成");

            PdfPrint.PDFprint(file, printName);

        } catch (Exception e) {
            return ResultVo.fail();

        }
        return ResultVo.ok();

    }

    //打印显示器二维码
    @CrossOrigin
    @GetMapping("print-qr-code/monitor/{deviceId}/{printName}")
    public ResultVo printMonitorQr(@PathVariable String deviceId,@PathVariable String printName) {
        if (StrUtil.isBlank(deviceId)) {
            return ResultVo.fail();
        }
        try {
            PrintVo printVo = printUtils.commonPrint(deviceId);
            MonitorVo monitorVo = JSON.parseObject(printVo.getString(), MonitorVo.class);

            String model = monitorVo.getMonitorModel();
            String sn = monitorVo.getMonitorSn();
            String id = monitorVo.getId();
            String quality = monitorVo.getQuality();
            Boolean passed = monitorVo.getPassed();
            String mark = monitorVo.getMark();
            String text = (monitorVo.getPoId() + "\n" + id + "\n" + sn + "\n" + model + "\n" + (passed ? "PASS" : "FAIL") + " " + quality + "\n" + (StrUtil.isBlank(mark) ? "" : mark));

            //在二维码下方添加文字（文字居中）
            pressText(text, printVo.getNewImageWithText(), printVo.getBufferedImage(), printVo.getFontStyle(), Color.black, printVo.getFont(), printVo.getWidth(), printVo.getHeight());

            String pdfPath = path + "/" + printVo.getTime() + ".pdf";

            PdfPrint.toPdf(printVo.getNewImageWithText(), pdfPath);

            File file = new File(pdfPath);
            //等待图片生成
            while (!file.exists()) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("生成");

            PdfPrint.PDFprint(file, printName);

        } catch (Exception e) {
            return ResultVo.fail();
        }
        return ResultVo.ok();
    }

}
